package com.h2cloud.JUCTest.reentrantReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @Package: com.h2cloud.JUCTest.reentrantReadWriteLock
 * @ClassName: readWriteLockTest
 * @Author: wulongkai
 * @CreateTime: 2024/1/10 20:06
 * @Description: 高并发读读不阻塞，写操作阻塞进队列，后续的读操作都阻塞，等前面的写操作完成再 unpark
 */
// debug fullTryAcquireShared
// code：else if (readerShouldBlock())
// condition：current.getName().equals("t3")
public class ReadWriteLockTest {


    public static void main(String[] args) {
        test2();
    }

    public static void test2() {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        new Thread(() -> {
            System.out.println("t1 读锁 操作加锁");
            lock.readLock().lock();
            System.out.println("t1 读锁 加锁成功");
            try {
                Thread.sleep(400000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.readLock().unlock();
            System.out.println("t1 读锁 解锁成功");
        }, "t1").start();


        new Thread(() -> {
            System.out.println("t3 读锁 操作加锁1");
            lock.readLock().lock();
            System.out.println("t3 读锁 加锁成功1");

            new Thread(() -> {
                System.out.println("t2 写锁 操作加锁");
                lock.writeLock().lock();
                System.out.println("t2 写锁 加锁成功");
                lock.writeLock().unlock();
                System.out.println("t2 写锁 解锁成功");
            }, "t2").start();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("t3 读锁 再操作加锁2");
            lock.readLock().lock();
            System.out.println("t3 读锁 再加锁成功2");

            lock.readLock().unlock();
            System.out.println("t3 读锁 解锁成功1");
            lock.readLock().unlock();
            System.out.println("t3 读锁 解锁成功2");
        }, "t3").start();
    }

    public static void test1() {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        new Thread(() -> {
            System.out.println("t1 读锁 操作加锁");
            lock.readLock().lock();
            System.out.println("t1 读锁 加锁成功");
            try {
                Thread.sleep(40000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.readLock().unlock();
            System.out.println("t1 读锁 解锁成功");
        }, "t1").start();


        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            System.out.println("t2 写锁 操作加锁");
            lock.writeLock().lock();
            System.out.println("t2 写锁 加锁成功");
            lock.writeLock().unlock();
            System.out.println("t2 写锁 解锁成功");
        }, "t2").start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            System.out.println("t3 读锁 操作加锁");
            lock.readLock().lock();
            System.out.println("t3 读锁 加锁成功");
            lock.readLock().unlock();
            System.out.println("t3 读锁 解锁成功");
        }, "t3").start();

    }

}
